package cn.buk.tms.eotms.entity;

import cn.buk.common.util.DateUtil;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import jakarta.persistence.*;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static java.util.regex.Pattern.compile;

@Entity
@Table(name="t240",	uniqueConstraints=@UniqueConstraint(name="uk_t240_enterprise_id_pnrno",	columnNames={"enterprise_id", "pnrNo"} ))
public class Pnr {

	private final static Logger logger = LogManager.getLogger(Pnr.class);

	@Id
	@Column(name="pnrid")
	@GeneratedValue(strategy= GenerationType.IDENTITY)
	private int id;
	
	@Column(length=7, nullable=false)
	private String pnrNo;
	
	@Column(name="enterprise_id", nullable=false)
	private int enterpriseId;

	/**
	 * 大编码，和pnrno配合，确定是否为同一个编码
	 */
	@Column(length = 7, name = "big_pnr")
	private String bigPnrNo;


	/**
	 * 第一程或单程的出发机场
	 */
	@Column(name = "dport", length = 3)
	private String departurePort;

	/**
	 * 第一程或单程的到达机场
	 */
	@Column(name = "aport", length = 3)
	private String arrivalPort;

	/**
	 * 第一程或单程的航班号
	 */
	@Column(name = "flightNo", length = 7)
	private String flightNo;

	/**
	 * 第一程或单程的出发日期
	 */
	@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
	@Temporal(TemporalType.DATE)
	@Column(name = "ddate")
	private Date departureDate;

	/**
	 * 第一程或单程的出发时间
	 */
	@Column(name = "dtime", length = 4)
	private String departureTime;

	/**
	 * 第一程或单程的预定的舱位
	 */
	@Column(length = 2)
	private String subClass;
	

	@Column(name="customer_id")
	private Integer customerId;

    /**
     * 预定该PNR的用户所使用的eterm用户名
     */
    @Column(length=32)
    private String etermUsername;

	/**
	 * 出票时限
	 */
	@Temporal(TemporalType.TIMESTAMP)
	private Date dzTime;

    /**
     * 出票状态
     * 0-未出票
     * 1-已出票
     */
    private Integer dzStatus=0;

    /**
     * 出票日期
     * 从t233中找到对应的编码，并将他的出票日期写入进来
     */
    @Temporal(TemporalType.DATE)
    private Date etdzDate;

    /**
     * 出票的office
     */
    @Column(length=6)
    private String etdzOffice;

    /**
     * 0 - 此编码正常状态
     * 1 - 此编码已取消
     */
    @Column(length=1)
    private Integer xeStatus=0;

    /**
     * 航段状态
     * --用于显示PNR中需要提醒业务员注意的航段，比如HX,NO等航段
     */
    @Column(length=10)
    private String segStatus;

    /**
     * 编码的处理状态
     * 0-不需要处理
     * 1-需要处理，取出pnrDetail，重新分析出票时限
     * 2-需要处理，取出pnrDetail, 重新分析pnrNo
     */
    private int status;
	
	
	@Transient
	private List<PnrFlight> flights;

	@Transient
	private List<PnrPassenger> passengers;

	@Transient
	private List<PnrTicket> tickets;

	/**
	 * 公布运价
	 */
	private int price;

	/**
	 * 实际销售运价
	 */
	private int parvalue;

	/**
	 * 税总额
	 */
	private int tax;

	@Transient
	private Double commRate;

	/**
	 * 公布运价
	 */
	@Column(name = "price_chd")
	private Integer chdPrice;

	/**
	 * 实际销售运价
	 */
	@Column(name = "parvalue_chd")
	private Integer chdParvalue;

	/**
	 * 税总额
	 */
	@Column(name = "tax_chd")
	private Integer chdTax;

	@Transient
	private Double chdCommRate;

	/**
	 * 公布运价
	 */
	@Column(name = "price_inf")
	private Integer infPrice;

	/**
	 * 实际销售运价
	 */
	@Column(name = "parvalue_inf")
	private Integer infParvalue;

	/**
	 * 税总额
	 */
	@Column(name = "tax_inf")
	private Integer infTax;

	@Transient
	private Double infCommRate;

	
	private int segCount;
	
	/**
	 * passenger count
	 */
	private int psgCount;
	
	private int ticketCount;

	@Column(name = "adult_count")
	private Integer adultCount;

	@Column(name = "child_count")
	private Integer childCount;

	@Column(name = "infant_count")
	private Integer infantCount;


	/**
	 * pnr中包含的ctcm数量
	 */
	@Column(name = "ctcm_count")
	private Integer ctcmCount;

	@Column(name = "ctct_count")
	private Integer ctctCount;
	
	@Lob
	@Basic(fetch=FetchType.LAZY)
	private String pnrDetail;
	
	@Transient
	private boolean pnrContentProcessed;
	
	@Column(length=2000)
	private String remark;
	
	/**
	 * PNR的清Q日期
	 */
	@Temporal(TemporalType.DATE)
	@Column(insertable=false)
	private Date issueDate;

	/**
	 * 0/null - 未监控
	 * 1 - 监控中, 检查NO/HX状态提醒
	 * 2 - 追位，编码中的位子被NO，或HN，则查航班，并定位
	 */
    private Integer monitoring = 0;


    /**
     * pnr状态是否已检查
     * 以下三个状态主要针对于状态为HX NO状态的PNR的处理
     */
    @Column(length=1)
    private String checkDone;

    /**
     * pnr状态检查时间
     */
    @Temporal(TemporalType.TIMESTAMP)
    private Date checkTime;

    /**
     * pnr状态检查用户名
     */
    @Column(length=20)
    private String checker;

	/**
	 * 该记录保存到数据库的时间, 创建时间
	 */
	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "create_time", updatable = false)
	private Date createTime;

    /**
     * 最后更新时间
     */
	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @Temporal(TemporalType.TIMESTAMP)
    @Column(insertable = false)
    private Date lastUpdate;

    /**
     * 冗余字段,保存最大的航班起飞日期
     */
	@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @Temporal(TemporalType.DATE)
    @Column(name="max_departure_date")
    private Date maxDepartureDate;

    /**
     * 冗余字段,保存最小的航班起飞日期
     */
	@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @Temporal(TemporalType.DATE)
    @Column(name="min_departure_date")
    private Date minDepartureDate;


    @Transient
    private String pnrCommitResult;

    /**
     * pnrCommitResult生成的时间
     */
    @Transient
    private Date opTime;

	@Column(length = 20)
	private String linkphone;

	/**
	 * 预订office
	 */
	@Column(name = "sd_office", length = 6)
	private String bookOfficeNo;

	/**
	 * 授权office
	 */
	@Transient
	private String authOfficeNo;

	/**
	 * 精简的编码内容
	 */
	@Transient
	private String compactPnrDetail;

	/**
	 * RT结果的状态
	 * 1 - 有效
	 * 0 - 无效
	 */
	@Transient
	private int rtResultStatus;

	/**
	 * 出票时限
	 */
	@Transient
	private String tktl;

	@Transient
	private String tktlDate;

	@Transient
	private String tktlTime;

    public String getUpdateTimeDesc() {
		if (lastUpdate == null) {
      return "";
    } else {
      return DateUtil.getUpdateTimeDesc(lastUpdate);
    }
	}


    /**
	 * @return the id
	 */
	public int getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(int id) {
		this.id = id;
	}

	/**
	 * @return the dzTime
	 */
	public Date getDzTime() {
		return dzTime;
	}

	/**
	 * @param dzTime the dzTime to set
	 */
	public void setDzTime(Date dzTime) {
		this.dzTime = dzTime;
	}

	/**
	 * @return the price
	 */
	public int getPrice() {
		return price;
	}

	/**
	 * @param price the price to set
	 */
	public void setPrice(int price) {
		this.price = price;
	}

	/**
	 * @return the tax
	 */
	public int getTax() {
		return tax;
	}

	/**
	 * @param tax the tax to set
	 */
	public void setTax(int tax) {
		this.tax = tax;
	}

	/**
	 * @return the segCount
	 */
	public int getSegCount() {
		return segCount;
	}

	/**
	 * @param segCount the segCount to set
	 */
	public void setSegCount(int segCount) {
		this.segCount = segCount;
	}

	/**
	 * @return the psgCount
	 */
	public int getPsgCount() {
		return psgCount;
	}

	/**
	 * @param psgCount the psgCount to set
	 */
	public void setPsgCount(int psgCount) {
		this.psgCount = psgCount;
	}

	/**
	 * @return the pnrDetail
	 */
	public String getPnrDetail() {
		return pnrDetail == null ? "" : pnrDetail;
	}

	/**
	 * @param pnrDetail the pnrDetail to set
	 */
	public void setPnrDetail(String pnrDetail) {
		this.pnrDetail = pnrDetail;
	}


	/**
	 * @return the pnrNo
	 */
	public String getPnrNo() {
		return this.pnrNo == null ? "" : this.pnrNo.trim();
	}

	/**
	 * @param pnrNo the pnrNo to set
	 */
	public void setPnrNo(String pnrNo) {
		if (pnrNo != null) {
      pnrNo = pnrNo.trim();
    }
		this.pnrNo = pnrNo;
	}

	/**
	 * @return the flights
	 */
	public List<PnrFlight> getFlights() {
		if (flights == null) {
      flights = new ArrayList<>();
    }
		return flights;
	}

	/**
	 * @param flights the flights to set
	 */
	public void setFlights(List<PnrFlight> flights) {
		this.flights = flights;
	}

	/**
	 * @return the passengers
	 */
	public List<PnrPassenger> getPassengers() {
		if (this.passengers == null) {
      this.passengers = new ArrayList<>();
    }
		return passengers;
	}

	/**
	 * @param passengers the passengers to set
	 */
	public void setPassengers(List<PnrPassenger> passengers) {
		this.passengers = passengers;
	}

	public List<PnrTicket> getTickets() {
		if (this.tickets == null) {
      this.tickets = new ArrayList<>();
    }
		return tickets;
	}

	public void setTickets(List<PnrTicket> tickets) {
		this.tickets = tickets;
	}

	public int getTicketCount() {
		return this.ticketCount;
	}

	public void setTicketCount(int ticketCount) {
		this.ticketCount = ticketCount;
	}


	public Date getIssueDate() {
		return issueDate;
	}

	public void setIssueDate(Date issueDate) {
		this.issueDate = issueDate;
	}

	/**
	 * @return the remark
	 */
	public String getRemark() {
		return remark;
	}

	/**
	 * @param remark the remark to set
	 */
	public void setRemark(String remark) {
		this.remark = remark;
	}

	/**
	 * @return the pnrContentProcessed
	 */
	public boolean isPnrContentProcessed() {
		return pnrContentProcessed;
	}

	/**
	 * @param pnrContentProcessed the pnrContentProcessed to set
	 */
	public void setPnrContentProcessed(boolean pnrContentProcessed) {
		this.pnrContentProcessed = pnrContentProcessed;
	}

	/**
	 * @return the customer
	 */
	public Integer getCustomer() {
		return customerId;
	}

	/**
	 * @param customer the customer to set
	 */
	public void setCustomer(Integer customer) {
		this.customerId = customer;
	}

	/**
	 * @return the enterpriseId
	 */
	public int getEnterpriseId() {
		return enterpriseId;
	}

	/**
	 * @param enterpriseId the enterpriseId to set
	 */
	public void setEnterpriseId(int enterpriseId) {
		this.enterpriseId = enterpriseId;
	}

    public Integer getDzStatus() {

        return dzStatus;
    }

    public void setDzStatus(Integer dzStatus) {
        this.dzStatus = dzStatus;
    }

    public String getSegStatus() {
        return segStatus;
    }

    public void setSegStatus(String segStatus) {
        this.segStatus = segStatus;
    }

    public String getCheckDone() {
        return checkDone;
    }

    public void setCheckDone(String checkDone) {
        this.checkDone = checkDone;
    }

    public Date getCheckTime() {
        return checkTime;
    }

    public void setCheckTime(Date checkTime) {
        this.checkTime = checkTime;
    }

    public String getChecker() {
        return checker;
    }

    public void setChecker(String checker) {
        this.checker = checker;
    }

    public Date getLastUpdate() {
        return lastUpdate;
    }

    public void setLastUpdate(Date lastUpdate) {
        this.lastUpdate = lastUpdate;
    }

    public String getEtermUsername() {
		if (this.etermUsername == null) {
      return "";
    } else {
      return etermUsername;
    }
	}

    public void setEtermUsername(String etermUsername) {
        this.etermUsername = etermUsername;
    }

    public String getPnrCommitResult() {
        return pnrCommitResult;
    }

    public void setPnrCommitResult(String pnrCommitResult) {
        if (pnrCommitResult.length() < 20) {
          return;
        }

        this.pnrCommitResult = pnrCommitResult;
    }

    public Date getOpTime() {
        return opTime;
    }

    public void setOpTime(Date opTime) {
        this.opTime = opTime;
    }



    public Date getEtdzDate() {
        return etdzDate;
    }

    public void setEtdzDate(Date etdzDate) {
        this.etdzDate = etdzDate;
    }

    public String getEtdzOffice() {
        return etdzOffice;
    }

    public void setEtdzOffice(String etdzOffice) {
        this.etdzOffice = etdzOffice;
    }

    public Integer getXeStatus() {
        if (this.xeStatus == null) {
          this.xeStatus = 0;
        }
        return xeStatus;
    }

    public void setXeStatus(Integer xeStatus) {
        this.xeStatus = xeStatus;
    }

    public int getIntXeStatus() {
        if (this.xeStatus == null) {
          return 0;
        } else {
          return this.xeStatus;
        }
    }

    public int getIntDzStatus() {
        if(this.dzStatus==null) {
          return 0;
        } else {
          return dzStatus;
        }
    }

    public Date getMinDepartureDate() {
        if (minDepartureDate == null && this.flights != null && this.flights.size() > 0) {
            try {
                minDepartureDate = DateUtil.convertToDate(flights.get(0).getFlight().getDepartureDate(),"yyyy-MM-dd");
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return minDepartureDate;
    }

    public void setMinDepartureDate(Date minDepartureDate) {
        this.minDepartureDate = minDepartureDate;
    }

    public Date getMaxDepartureDate() {
        if (maxDepartureDate == null && this.flights != null && this.flights.size() > 0) {
            int i = flights.size() - 1;
            try {
                maxDepartureDate = DateUtil.convertToDate(flights.get(i).getFlight().getDepartureDate(),"yyyy-MM-dd");
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return maxDepartureDate;
    }

    public void setMaxDepartureDate(Date maxDepartureDate) {
        this.maxDepartureDate = maxDepartureDate;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

	public String getDeparturePort() {
		return departurePort;
	}

	public void setDeparturePort(String departurePort) {
		this.departurePort = departurePort;
	}

	public String getArrivalPort() {
		return arrivalPort;
	}

	public void setArrivalPort(String arrivalPort) {
		this.arrivalPort = arrivalPort;
	}

	public String getFlightNo() {
		return flightNo;
	}

	public void setFlightNo(String flightNo) {
		this.flightNo = flightNo;
	}

	public Date getDepartureDate() {
		return departureDate;
	}

	public void setDepartureDate(Date departureDate) {
		this.departureDate = departureDate;
	}

	public String getSubClass() {
		return subClass;
	}

	public void setSubClass(String subClass) {
		this.subClass = subClass;
	}

	public String getDepartureTime() {
		return departureTime;
	}

	public void setDepartureTime(String departureTime) {
		this.departureTime = departureTime;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public String getCarrier() {
		if (flightNo == null) {
      return  "";
    } else {
      return flightNo.substring(0,2);
    }

	}

	public String getLinkphone() {
		if (this.linkphone == null) {
      return "";
    } else {
      return linkphone.trim();
    }
	}

	public void setLinkphone(String linkphone) {
		this.linkphone = linkphone;
	}

	public String getBookOfficeNo() {
		if (bookOfficeNo == null) {
      return "";
    } else {
      return bookOfficeNo;
    }
	}

	public String getAuthOfficeNo() {
		if (authOfficeNo == null) {
      return "";
    } else {
      return authOfficeNo;
    }
	}

	public void setAuthOfficeNo(String authOfficeNo) {
		this.authOfficeNo = authOfficeNo;
	}

	public String getCompactPnrDetail() {
		return compactPnrDetail;
	}

	public void setCompactPnrDetail(String compactPnrDetail) {
		this.compactPnrDetail = compactPnrDetail;
	}

	public String getBigPnrNo() {
		return this.bigPnrNo == null ? "" : bigPnrNo;
	}

	public void setBigPnrNo(String bigPnrNo) {
		if (bigPnrNo != null && bigPnrNo.trim().length() > 7) {
			logger.info("bigPnrNo: " + bigPnrNo);
			this.bigPnrNo = bigPnrNo.trim().substring(0, 7);
		} else {
			this.bigPnrNo = bigPnrNo;
		}
	}

	public int getCtcmCount() {
		return ctcmCount == null ? 0 : ctcmCount;
	}

	public void setCtcmCount(Integer ctcmCount) {
		this.ctcmCount = ctcmCount;
	}

	/**
	 * 检查OFFICE NO的格式
	 * @param officeNo
	 * @return
	 */
	public static boolean testOfficeNoFormat(final String officeNo) {
		String regEx="[A-Z]{3}[0-9]{3}";
		return compile(regEx).matcher(officeNo).find();
	}

	public int getRtResultStatus() {
		return rtResultStatus;
	}

	public void setRtResultStatus(int rtResultStatus) {
		this.rtResultStatus = rtResultStatus;
	}

	public int getParvalue() {
		return parvalue;
	}

	public void setParvalue(int parvalue) {
		this.parvalue = parvalue;
	}

	public String getTktl() {
		return tktl;
	}

	public void setTktl(String tktl) {
		this.tktl = tktl;
	}

	public String getTktlTime() {
		return tktlTime;
	}

	public void setTktlTime(String tktlTime) {
		this.tktlTime = tktlTime;
	}

	public String getTktlDate() {
		return tktlDate;
	}

	public void setTktlDate(String tktlDate) {
		this.tktlDate = tktlDate;
	}

	public Integer getChdPrice() {
		return chdPrice == null ? 0 : chdPrice;
	}

	public void setChdPrice(Integer chdPrice) {
		this.chdPrice = chdPrice;
	}

	public Integer getChdParvalue() {
		return chdParvalue == null ? 0 : chdParvalue;
	}

	public void setChdParvalue(Integer chdParvalue) {
		this.chdParvalue = chdParvalue;
	}

	public Integer getChdTax() {
		return chdTax == null ? 0 : chdTax;
	}

	public void setChdTax(Integer chdTax) {
		this.chdTax = chdTax;
	}

	public int getAdultCount() {
		return adultCount == null ? 0 : adultCount;
	}

	public void setAdultCount(Integer adultCount) {
		this.adultCount = adultCount;
	}

	public Integer getChildCount() {
		return childCount == null ? 0 : childCount;
	}

	public void setChildCount(Integer childCount) {
		this.childCount = childCount;
	}

	public Double getCommRate() {
		return commRate == null ? 0 : commRate;
	}

	public void setCommRate(Double commRate) {
		this.commRate = commRate;
	}

	public Double getChdCommRate() {
		return chdCommRate == null ? 0 : chdCommRate;
	}

	public void setChdCommRate(Double chdCommRate) {
		this.chdCommRate = chdCommRate;
	}

	public Integer getInfPrice() {
		return infPrice == null ? 0 : infPrice;
	}

	public void setInfPrice(Integer infPrice) {
		this.infPrice = infPrice;
	}

	public Integer getInfParvalue() {
		return infParvalue == null ? 0 : infParvalue;
	}

	public void setInfParvalue(Integer infParvalue) {
		this.infParvalue = infParvalue;
	}

	public Integer getInfTax() {
		return infTax == null ? 0 : infTax;
	}

	public void setInfTax(Integer infTax) {
		this.infTax = infTax;
	}

	public Double getInfCommRate() {
		return infCommRate == null ? 0 : infCommRate;
	}

	public void setInfCommRate(Double infCommRate) {
		this.infCommRate = infCommRate;
	}

	public int getInfantCount() {
		return infantCount == null ? 0 : infantCount;
	}

	public void setInfantCount(Integer infantCount) {
		this.infantCount = infantCount;
	}

    public Integer getMonitoring() {
        return monitoring;
    }

    public void setMonitoring(Integer monitoring) {
        this.monitoring = monitoring;
    }

	public void setBookOfficeNo(String bookOfficeNo) {
		this.bookOfficeNo = bookOfficeNo;
	}

	public Integer getCtctCount() {
		return ctctCount;
	}

	public void setCtctCount(Integer ctctCount) {
		this.ctctCount = ctctCount;
	}
}
